﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Jermaine
{
    /// <summary>
    /// 反射工具
    /// </summary>
    public class Reflector
    {

        #region 字段
        private static readonly Dictionary<string, PropertyInfo[]> PropertyInfoStorage;
        private static readonly Dictionary<string, FieldInfo[]> FieldInfoStorage;
        private static readonly Dictionary<string, MethodInfo[]> MethodInfoStorage;
        private static readonly Dictionary<string, MemberInfo[]> MemberInfoStorage;
        #endregion

        #region 构造器
        static Reflector() {
            PropertyInfoStorage = new Dictionary<string, PropertyInfo[]>();
            FieldInfoStorage = new Dictionary<string, FieldInfo[]>();
            MethodInfoStorage = new Dictionary<string, MethodInfo[]>();
            MemberInfoStorage = new Dictionary<string, MemberInfo[]>();
        }

        private Reflector() { }
        #endregion

        #region 是否存在成员
        /// <summary>
        /// 是否存在属性字段方法或者成员
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name">名字</param>
        /// <returns></returns>
        public static Boolean Exists<T>(string name) {
            return (GetProperty<T>(name) != null) ||
               (GetField<T>(name) != null) ||
               (GetMethod<T>(name) != null) ||
               (GetMember<T>(name) != null);
        }

        /// <summary>
        /// 是否存在属性字段方法或者成员
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="name">名字</param>
        /// <returns></returns>
        public static Boolean Exists(Type type, string name) {
            return (GetProperty(type, name) != null) ||
                (GetField(type, name) != null) ||
                (GetMethod(type, name) != null) ||
                (GetMember(type, name) != null);
        }
        #endregion

        #region 属性
        /// <summary>
        /// 获取所有属性名字
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static String[] GetPropertiesName<T>() {
            return GetProperties<T>().Select(o => o.Name).ToArray();
        }

        /// <summary>
        /// 获取所有属性名字
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static String[] GetPropertiesName(Type type) {
            return GetProperties(type).Select(o => o.Name).ToArray();
        }

        /// <summary>
        /// 获取所有属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static PropertyInfo[] GetProperties<T>() {
            var type = typeof(T);
            return GetProperties(type);
        }

        /// <summary>
        /// 获取所有属性
        /// </summary>
        /// <param name="type">类型</param>
        /// <returns></returns>
        public static PropertyInfo[] GetProperties(Type type) {
            var key = type.FullName;
            if (PropertyInfoStorage.ContainsKey(key)) {
                return PropertyInfoStorage[key];
            }

            var propertyInfo = type.GetProperties();

            if (propertyInfo == null) {
                throw new MissingMemberException();
            }
            PropertyInfoStorage.Add(key, propertyInfo);

            return propertyInfo;
        }

        /// <summary>
        /// 获取属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="propertyName">属性名</param>
        /// <returns></returns>
        public static PropertyInfo GetProperty<T>(string propertyName) {
            var propertyInfo = GetProperties<T>();
            return propertyInfo.Where(o => o.Name == propertyName).FirstOrDefault();
        }

        /// <summary>
        /// 获取属性
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="propertyName">属性名</param>
        /// <returns></returns>
        public static PropertyInfo GetProperty(Type type, string propertyName) {
            var propertyInfo = GetProperties(type);
            return propertyInfo.Where(o => o.Name == propertyName).FirstOrDefault();
        }

        /// <summary>
        /// 获取属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="index">属性索引</param>
        /// <returns></returns>
        public static PropertyInfo GetProperty<T>(int index) {
            return GetProperty(typeof(T), index);
        }

        /// <summary>
        /// 获取属性
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="index">属性索引</param>
        /// <returns></returns>
        public static PropertyInfo GetProperty(Type type, int index) {
            var propertyInfo = GetProperties(type);
            if (index > propertyInfo.Length - 1) {
                throw new IndexOutOfRangeException();
            }
            return propertyInfo[index];
        }

        #endregion

        #region 字段
        /// <summary>
        /// 获取所有字段的名字
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public String[] GetFieldsName<T>() {
            return GetFields<T>().Select(o => o.Name).ToArray();
        }

        /// <summary>
        /// 获取所有字段的名字
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public String[] GetFieldsName(Type type) {
            return GetFields(type).Select(o => o.Name).ToArray();
        }


        /// <summary>
        /// 获取所有字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static FieldInfo[] GetFields<T>() {
            var type = typeof(T);
            return GetFields(type);
        }

        /// <summary>
        /// 获取所有字段
        /// </summary>
        /// <param name="type">类型</param>
        /// <returns></returns>
        public static FieldInfo[] GetFields(Type type) {
            var key = type.FullName;
            if (FieldInfoStorage.ContainsKey(key)) {
                return FieldInfoStorage[key];
            }

            var fieldInfo = type.GetFields();
            if (fieldInfo == null) {
                throw new MissingFieldException();
            }
            FieldInfoStorage.Add(key, fieldInfo);
            return fieldInfo;
        }

        /// <summary>
        /// 获取字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="fieldName">字段名</param>
        /// <returns></returns>
        public static FieldInfo GetField<T>(string fieldName) {
            var fieldInfo = GetFields<T>();
            return fieldInfo.Where(o => o.Name == fieldName).FirstOrDefault();
        }

        /// <summary>
        ///  获取字段
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="fieldName">字段名</param>
        /// <returns></returns>
        public static FieldInfo GetField(Type type, string fieldName) {
            var fieldInfo = GetFields(type);
            return fieldInfo.Where(o => o.Name == fieldName).FirstOrDefault();
        }

        /// <summary>
        /// 获取字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="index">字段索引</param>
        /// <returns></returns>
        public static FieldInfo GetField<T>(int index) {
            return GetField(typeof(T), index);
        }

        /// <summary>
        /// 获取字段
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="index">字段索引</param>
        /// <returns></returns>
        public static FieldInfo GetField(Type type, int index) {
            var fieldInfo = GetFields(type);

            if (index > fieldInfo.Length - 1) {
                throw new IndexOutOfRangeException();
            }
            return fieldInfo[index];
        }
        #endregion

        #region 方法
        /// <summary>
        /// 获取所有方法名
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static String[] GetMethodsName<T>() {
            return GetMethods<T>().Select(o => o.Name).ToArray();
        }

        /// <summary>
        /// 获取所有方法名
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static String[] GetMethodsName(Type type) {
            return GetMethods(type).Select(o => o.Name).ToArray();
        }
        /// <summary>
        /// 获取所有方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static MethodInfo[] GetMethods<T>() {
            var type = typeof(T);
            return GetMethods(type);

        }

        /// <summary>
        /// 获取所有方法
        /// </summary>
        /// <param name="type">类型</param>
        /// <returns></returns>
        public static MethodInfo[] GetMethods(Type type) {

            var key = type.FullName;
            if (MethodInfoStorage.ContainsKey(key)) {
                return MethodInfoStorage[key];
            }

            var methodInfo = type.GetMethods();
            if (methodInfo == null) {
                throw new MissingMethodException();
            }
            MethodInfoStorage.Add(key, methodInfo);
            return methodInfo;

        }

        /// <summary>
        /// 获取方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="methodName">方法名</param>
        /// <returns></returns>
        public static MethodInfo GetMethod<T>(string methodName) {
            var methodInfo = GetMethods<T>();
            return methodInfo.Where(o => o.Name == methodName).FirstOrDefault();
        }

        /// <summary>
        /// 获取方法
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="methodName">方法名</param>
        /// <returns></returns>
        public static MethodInfo GetMethod(Type type, string methodName) {
            var methodInfo = GetMethods(type);
            return methodInfo.Where(o => o.Name == methodName).FirstOrDefault();
        }

        /// <summary>
        /// 获取方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="index">方法索引</param>
        /// <returns></returns>
        public static MethodInfo GetMethod<T>(int index) {
            return GetMethod(typeof(T), index);
        }

        /// <summary>
        /// 获取方法
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="index">方法索引</param>
        /// <returns></returns>
        public static MethodInfo GetMethod(Type type, int index) {
            var methodInfo = GetMethods(type);
            if (index > methodInfo.Length - 1) {
                throw new IndexOutOfRangeException();
            }

            return methodInfo[index];
        }
        #endregion

        #region 成员
        /// <summary>
        /// 获取所有成员
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static MemberInfo[] GetMembers<T>() {
            var type = typeof(T);
            return GetMembers(type);
        }

        /// <summary>
        /// 获取所有成员
        /// </summary>
        /// <param name="type">类型</param>
        /// <returns></returns>
        public static MemberInfo[] GetMembers(Type type) {
            var key = type.FullName;
            if (MemberInfoStorage.ContainsKey(key)) {
                return MethodInfoStorage[key];
            }

            var memberInfo = type.GetMembers();
            if (memberInfo == null) {
                throw new MissingMemberException();
            }
            MemberInfoStorage.Add(key, memberInfo);
            return memberInfo;
        }

        /// <summary>
        /// 获取成员
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="memberName">成员名</param>
        /// <returns></returns>
        public static MemberInfo GetMember<T>(string memberName) {
            var memberInfo = GetMembers<T>();
            return memberInfo.Where(o => o.Name == memberName).FirstOrDefault();
        }

        /// <summary>
        /// 获取成员
        /// </summary>
        /// <param name="type"></param>
        /// <param name="memberName">成员名</param>
        /// <returns></returns>
        public static MemberInfo GetMember(Type type, string memberName) {
            var memberInfo = GetMembers(type);
            return memberInfo.Where(o => o.Name == memberName).FirstOrDefault();
        }
        #endregion

        #region 属性操作
        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="propertyName">属性名</param>
        /// <returns></returns>
        public static TValue GetPropertyValue<T, TValue>(T o, string propertyName) where T : new() {
            var propertyInfo = GetProperty<T>(propertyName);
            if (propertyInfo == null) {
                throw new MissingMemberException(propertyName);
            }
            return (TValue)propertyInfo.GetValue(o, null);
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="propertyName">属性名</param>
        /// <returns></returns>
        public static TValue GetPropertyValue<TValue>(Object o, string propertyName) {
            if (o == null) {
                throw new ArgumentNullException();
            }
            var propertyInfo = GetProperty(o.GetType(), propertyName);
            if (propertyInfo == null) {
                throw new MissingMemberException(propertyName);
            }
            return (TValue)propertyInfo.GetValue(o, null);
        }

        /// <summary>
        /// 设定属性值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="propertyName">属性名</param>
        /// <param name="value">值</param>
        public static void SetPropertyValue<T, TValue>(T o, string propertyName, TValue value) where T : new() {
            var propertyInfo = GetProperty<T>(propertyName);
            if (propertyInfo == null) {
                throw new MissingMemberException(propertyName);
            }
            propertyInfo.SetValue(o, value, null);
        }

        /// <summary>
        /// 设定属性值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="propertyName">属性名</param>
        /// <param name="value">值</param>
        public static void SetPropertyValue<TValue>(Object o, string propertyName, TValue value) {
            if (o == null) {
                throw new ArgumentNullException();
            }
            var propertyInfo = GetProperty(o.GetType(), propertyName);
            if (propertyInfo == null) {
                throw new MissingMemberException(propertyName);
            }
            propertyInfo.SetValue(o, value, null);
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="index">属性索引</param>
        /// <returns></returns>
        public static TValue GetPropertyValue<T, TValue>(T o, int index) where T : new() {
            var propertyInfo = GetProperty<T>(index);
            return (TValue)propertyInfo.GetValue(o, null);
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="index">索引</param>
        /// <returns></returns>
        public static TValue GetPropertyValue<TValue>(Object o, int index) {
            if (o == null) {
                throw new ArgumentNullException();
            }
            var propertyInfo = GetProperty(o.GetType(), index);
            return (TValue)propertyInfo.GetValue(o, null);
        }

        /// <summary>
        /// 设定属性值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="index">属性索引</param>
        /// <param name="value">值</param>
        public static void SetPropertyValue<T, TValue>(T o, int index, TValue value) where T : new() {
            var propertyInfo = GetProperty<T>(index);
            propertyInfo.SetValue(o, value, null);
        }

        /// <summary>
        /// 设定属性值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="index">属性索引</param>
        /// <param name="value">值</param>
        public static void SetPropertyValue<TValue>(Object o, int index, TValue value) {
            if (o == null) {
                throw new ArgumentNullException();
            }
            var propertyInfo = GetProperty(o.GetType(), index);
            propertyInfo.SetValue(o, value, null);
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="index">属性索引</param>
        /// <returns></returns>
        public static TValue GetPropertyValue<T, TValue>(T o, String propertyName, Object index) where T : new() {
            var propertyInfo = GetProperty<T>(propertyName);
            if (propertyInfo == null) {
                throw new MissingMemberException(propertyName);
            }
            return (TValue)propertyInfo.GetValue(o, new Object[] { index });
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="index">索引</param>
        /// <returns></returns>
        public static TValue GetPropertyValue<TValue>(Object o, String propertyName, Object index) {
            if (o == null) {
                throw new ArgumentNullException();
            }
            var propertyInfo = GetProperty(o.GetType(), propertyName);
            if (propertyInfo == null) {
                throw new MissingMemberException(propertyName);
            }
            return (TValue)propertyInfo.GetValue(o, new Object[] { index });
        }

        /// <summary>
        /// 设定属性值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="index">属性索引</param>
        /// <param name="value">值</param>
        public static void SetPropertyValue<T, TValue>(T o, String propertyName, Object index, TValue value) where T : new() {
            var propertyInfo = GetProperty<T>(propertyName);
            if (propertyInfo == null) {
                throw new MissingMemberException(propertyName);
            }
            propertyInfo.SetValue(o, value, new Object[] { index });
        }

        /// <summary>
        /// 设定属性值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="index">属性索引</param>
        /// <param name="value">值</param>
        public static void SetPropertyValue<TValue>(Object o, String propertyName, Object index, TValue value) {
            if (o == null) {
                throw new ArgumentNullException();
            }
            var propertyInfo = GetProperty(o.GetType(), propertyName);
            if (propertyInfo == null) {
                throw new MissingMemberException(propertyName);
            }
            propertyInfo.SetValue(o, value, new Object[] { index });
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="propertyName">属性名</param>
        /// <returns></returns>
        public static TValue GetPropertyValue<T, TValue>(string propertyName) {
            var propertyInfo = GetProperty<T>(propertyName);
            if (propertyInfo == null) {
                throw new MissingMemberException(propertyName);
            }
            return (TValue)propertyInfo.GetValue(null, null);
        }

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="propertyName">属性名</param>
        /// <returns></returns>
        public static TValue GetPropertyValue<TValue>(Type type, string propertyName) {

            var propertyInfo = GetProperty(type, propertyName);
            if (propertyInfo == null) {
                throw new MissingMemberException(propertyName);
            }
            return (TValue)propertyInfo.GetValue(null, null);
        }

        /// <summary>
        /// 设定属性值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="propertyName">属性名</param>
        /// <param name="value">值</param>
        public static void SetPropertyValue<T, TValue>(string propertyName, TValue value) {
            var propertyInfo = GetProperty<T>(propertyName);
            if (propertyInfo == null) {
                throw new MissingMemberException(propertyName);
            }
            propertyInfo.SetValue(null, value, null);
        }

        /// <summary>
        /// 设定属性值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="propertyName">属性名</param>
        /// <param name="value">值</param>
        public static void SetPropertyValue<TValue>(Type type, string propertyName, TValue value) {

            var propertyInfo = GetProperty(type, propertyName);
            if (propertyInfo == null) {
                throw new MissingMemberException(propertyName);
            }
            propertyInfo.SetValue(null, value, null);
        }

        #endregion

        #region 字段操作
        /// <summary>
        /// 获取字段值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="fieldName">字段名</param>
        /// <returns></returns>
        public static TValue GetFieldValue<T, TValue>(T o, string fieldName) where T : new() {
            var fieldInfo = GetField<T>(fieldName);
            if (fieldInfo == null) {
                throw new MissingFieldException(fieldName);
            }

            return (TValue)fieldInfo.GetValue(o);
        }

        /// <summary>
        /// 获取字段值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="fieldName">字段名</param>
        /// <returns></returns>
        public static TValue GetFieldValue<TValue>(Object o, string fieldName) {
            if (o == null) {
                throw new ArgumentNullException();
            }
            var fieldInfo = GetField(o.GetType(), fieldName);
            if (fieldInfo == null) {
                throw new MissingFieldException(fieldName);
            }

            return (TValue)fieldInfo.GetValue(o);
        }

        /// <summary>
        /// 设定字段值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="fieldName">字段名</param>
        /// <param name="value">值</param>
        public static void SetFieldValue<T, TValue>(T o, string fieldName, TValue value) where T : new() {
            var fieldInfo = GetField<T>(fieldName);
            if (fieldInfo == null) {
                throw new MissingFieldException(fieldName);
            }

            fieldInfo.SetValue(o, value);
        }

        /// <summary>
        /// 设定字段值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="fieldName">字段名</param>
        /// <param name="value">值</param>
        public static void SetFieldValue<TValue>(Object o, string fieldName, TValue value) {
            if (o == null) {
                throw new ArgumentNullException();
            }
            var fieldInfo = GetField(o.GetType(), fieldName);
            if (fieldInfo == null) {
                throw new MissingFieldException(fieldName);
            }

            fieldInfo.SetValue(o, value);
        }

        /// <summary>
        /// 获取字段值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="index">字段索引</param>
        /// <returns></returns>
        public static TValue GetFieldValue<T, TValue>(T o, int index) where T : new() {
            var fieldInfo = GetField<T>(index);
            return (TValue)fieldInfo.GetValue(o);
        }

        /// <summary>
        /// 获取字段值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="index">字段索引</param>
        /// <returns></returns>
        public static TValue GetFieldValue<TValue>(Object o, int index) {
            if (o == null) {
                throw new ArgumentNullException();
            }
            var fieldInfo = GetField(o.GetType(), index);
            return (TValue)fieldInfo.GetValue(o);
        }

        /// <summary>
        /// 设定字段值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="index">字段索引</param>
        /// <param name="value">值</param>
        public static void SetFieldValue<T, TValue>(T o, int index, TValue value) where T : new() {
            var fieldInfo = GetField<T>(index);
            fieldInfo.SetValue(o, value);
        }

        /// <summary>
        /// 设定字段值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="index">字段索引</param>
        /// <param name="value">值</param>
        public static void SetFieldValue<TValue>(Object o, int index, TValue value) {
            if (o == null) {
                throw new ArgumentNullException();
            }
            var fieldInfo = GetField(o.GetType(), index);
            fieldInfo.SetValue(o, value);
        }


        /// <summary>
        /// 获取静态字段值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="fieldName">字段名</param>
        /// <returns></returns>
        public static TValue GetFieldValue<T, TValue>(string fieldName) {
            var fieldInfo = GetField<T>(fieldName);
            if (fieldInfo == null) {
                throw new MissingFieldException(fieldName);
            }

            return (TValue)fieldInfo.GetValue(null);
        }

        /// <summary>
        /// 获取静态字段值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="fieldName">字段名</param>
        /// <returns></returns>
        public static TValue GetFieldValue<TValue>(Type type, string fieldName) {
            var fieldInfo = GetField(type, fieldName);
            if (fieldInfo == null) {
                throw new MissingFieldException(fieldName);
            }

            return (TValue)fieldInfo.GetValue(null);
        }

        /// <summary>
        /// 设定静态字段值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="fieldName">字段名</param>
        /// <param name="value">值</param>
        public static void SetFieldValue<T, TValue>(string fieldName, TValue value) {
            var fieldInfo = GetField<T>(fieldName);
            if (fieldInfo == null) {
                throw new MissingFieldException(fieldName);
            }

            fieldInfo.SetValue(null, value);
        }

        /// <summary>
        /// 设定静态字段值
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="fieldName">字段名</param>
        /// <param name="value">值</param>
        public static void SetFieldValue<TValue>(Type type, string fieldName, TValue value) {

            var fieldInfo = GetField(type, fieldName);
            if (fieldInfo == null) {
                throw new MissingFieldException(fieldName);
            }

            fieldInfo.SetValue(null, value);
        }

        #endregion

        #region 调用方法
        /// <summary>
        /// 调用方法，有返回值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="methodName">方法名</param>
        /// <param name="args">参数</param>
        /// <returns></returns>
        public static TResult Call<T, TResult>(T o, string methodName, params Object[] args) where T : new() {
            var methodInfo = GetMethod<T>(methodName);
            if (methodInfo == null) {
                throw new MissingMethodException(methodName);
            }

            return (TResult)methodInfo.Invoke(o, args);
        }

        /// <summary>
        /// 调用方法，有返回值
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="methodName">方法名</param>
        /// <param name="args">参数</param>
        /// <returns></returns>
        public static TResult Call<TResult>(Object o, string methodName, params Object[] args) {
            if (o == null) {
                throw new ArgumentNullException();
            }
            var methodInfo = GetMethod(o.GetType(), methodName);
            if (methodInfo == null) {
                throw new MissingMethodException(methodName);
            }

            return (TResult)methodInfo.Invoke(o, args);
        }

        /// <summary>
        /// 调用静态方法，有返回值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="methodName">方法名</param>
        /// <param name="args">参数</param>
        /// <returns></returns>
        public static TResult Call<T, TResult>(String methodName, params Object[] args) {
            var methodInfo = GetMethod<T>(methodName);
            if (methodInfo == null) {
                throw new MissingMethodException(methodName);
            }

            return (TResult)methodInfo.Invoke(null, args);
        }

        /// <summary>
        /// 调用静态方法,有返回值
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="type"></param>
        /// <param name="methodName">方法名</param>
        /// <param name="args">参数</param>
        /// <returns></returns>
        public static TResult Call<TResult>(Type type, String methodName, params Object[] args) {
            var methodInfo = GetMethod(type, methodName);
            if (methodInfo == null) {
                throw new MissingMethodException(methodName);
            }

            return (TResult)methodInfo.Invoke(null, args);
        }

        /// <summary>
        /// 调用方法，有返回值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="index">方法索引</param>
        /// <param name="args">参数</param>
        /// <returns></returns>
        public static TResult Call<T, TResult>(T o, int index, params Object[] args) where T : new() {
            var methodInfo = GetMethod<T>(index);
            return (TResult)methodInfo.Invoke(o, args);
        }

        /// <summary>
        /// 调用方法，有返回值
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="o">实例</param>
        /// <param name="index">索引</param>
        /// <param name="args">参数</param>
        /// <returns></returns>
        public static TResult Call<TResult>(Object o, int index, params Object[] args) {
            if (o == null) {
                throw new ArgumentNullException();
            }
            var methodInfo = GetMethod(o.GetType(), index);
            return (TResult)methodInfo.Invoke(o, args);
        }

        /// <summary>
        /// 静态方法调用,有返回值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="index">索引</param>
        /// <param name="args">参数</param>
        /// <returns></returns>
        public static TResult Call<T, TResult>(int index, params Object[] args) {
            var methodInfo = GetMethod<T>(index);
            return (TResult)methodInfo.Invoke(null, args);
        }

        /// <summary>
        /// 静态方法调用,有返回值
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="type"></param>
        /// <param name="index">索引</param>
        /// <param name="args">参数</param>
        /// <returns></returns>
        public static TResult Call<TResult>(Type type, int index, params Object[] args) {
            var methodInfo = GetMethod(type, index);
            return (TResult)methodInfo.Invoke(null, args);
        }

        /// <summary>
        /// 调用方法，无返回值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o"></param>
        /// <param name="methodName"></param>
        /// <param name="args"></param>
        public static void Call<T>(T o, string methodName, params Object[] args) where T : new() {
            var methodInfo = GetMethod<T>(methodName);
            if (methodInfo == null) {
                throw new MissingMethodException(methodName);
            }

            methodInfo.Invoke(o, args);
        }

        /// <summary>
        /// 调用方法，无返回值
        /// </summary>
        /// <param name="o"></param>
        /// <param name="methodName"></param>
        /// <param name="args"></param>
        public static void Call(Object o, string methodName, params Object[] args) {
            if (o == null) {
                throw new ArgumentNullException();
            }
            var methodInfo = GetMethod(o.GetType(), methodName);
            if (methodInfo == null) {
                throw new MissingMethodException(methodName);
            }

            methodInfo.Invoke(o, args);
        }

        /// <summary>
        /// 调用静态方法，无返回值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="methodName"></param>
        /// <param name="args"></param>
        public static void Call<T>(String methodName, params Object[] args) {
            var methodInfo = GetMethod<T>(methodName);
            if (methodInfo == null) {
                throw new MissingMethodException(methodName);
            }

            methodInfo.Invoke(null, args);
        }

        /// <summary>
        /// 调用静态方法，无返回值
        /// </summary>
        /// <param name="type"></param>
        /// <param name="methodName"></param>
        /// <param name="args"></param>
        public static void Call(Type type, String methodName, params Object[] args) {
            var methodInfo = GetMethod(type, methodName);
            if (methodInfo == null) {
                throw new MissingMethodException(methodName);
            }

            methodInfo.Invoke(null, args);
        }

        /// <summary>
        /// 调用方法，无返回值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o"></param>
        /// <param name="index"></param>
        /// <param name="args"></param>
        public static void Call<T>(T o, int index, params Object[] args) where T : new() {
            var methodInfo = GetMethod<T>(index);
            methodInfo.Invoke(o, args);
        }

        /// <summary>
        /// 调用方法，无返回值
        /// </summary>
        /// <param name="o"></param>
        /// <param name="index"></param>
        /// <param name="args"></param>
        public static void Call(Object o, int index, params Object[] args) {
            if (o == null) {
                throw new ArgumentNullException();
            }
            var methodInfo = GetMethod(o.GetType(), index);
            methodInfo.Invoke(o, args);
        }

        /// <summary>
        /// 调用方法，无返回值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="index"></param>
        /// <param name="args"></param>
        public static void Call<T>(int index, params Object[] args) {
            var methodInfo = GetMethod<T>(index);
            methodInfo.Invoke(null, args);
        }

        /// <summary>
        /// 调用方法，无返回值
        /// </summary>
        /// <param name="type"></param>
        /// <param name="index"></param>
        /// <param name="args"></param>
        public static void Call(Type type, int index, params Object[] args) {
            var methodInfo = GetMethod(type, index);
            methodInfo.Invoke(null, args);
        }

        #endregion

    }
}
